package nostalgia.lastfm;

import nostalgia.gui.IProgressRunnable;
import nostalgia.lastfm.model.Weeklychartlist;
import nostalgia.lastfm.model.Weeklytrackchart;
import nostalgia.UserConfiguration;

import java.util.*;

public class LastfmChartDataReader implements IProgressRunnable {
    private String type;
    private String who;
    private List<Weeklytrackchart> data = new ArrayList<Weeklytrackchart>();

    public static LastfmChartDataReader getDefaultInstance() {
        return new LastfmChartDataReader("user", UserConfiguration.getInstsance().getLastFmUsername());       
    }

    public LastfmChartDataReader(String type, String who) {
        this.type = type;
        this.who = who;
    }

    public String getWho() {
        return who;
    }

    public String getType() {
        return type;
    }

    protected void read(IProgressCallback progresssCallback) {
        Weeklychartlist chartlist = null;
        Iterator<Weeklychartlist> chartLists = LastfmData.getInstance().getData().getWeeklychartlist().iterator();
        while(chartLists.hasNext()) {
            Weeklychartlist item = chartLists.next();
            if((type.equals("user") && item.getUser() != null && item.getUser().equals(who))
                || (type.equals("group") && item.getGroup() != null && item.getGroup().equals(who))) {
                chartlist = item;
                break;
            }
        }
        Calendar yesterday = Calendar.getInstance();
        yesterday.add(Calendar.DAY_OF_YEAR, -1);
        if(chartlist == null || chartlist.getUpdated() == null || chartlist.getUpdated() < yesterday.getTime().getTime()) {
            try {
                if(progresssCallback != null) {
                    progresssCallback.updateStatus("Reading chart list");
                }
                Weeklychartlist newchartlist = LastfmQuery.queryWeeklychartlist(type, who);
                newchartlist.setUpdated(new Date().getTime());
                if(chartlist != null) {
                    LastfmData.getInstance().getData().getWeeklychartlist().remove(chartlist);
                }
                chartlist = newchartlist;
                LastfmData.getInstance().getData().getWeeklychartlist().add(chartlist);
            }
            catch(LastfmNotFoundException e) {
                if(progresssCallback != null) {
                    progresssCallback.error("Last.fm " + type + " " + who + " not found");
                }
            }
            catch(LastfmQueryException e) {
                if(progresssCallback != null) {
                    progresssCallback.error("Error reading " + type + " " + who + " chart list");
                }
            }
        }
        if(chartlist != null) {
            Iterator<Weeklychartlist.Chart> it = chartlist.getChart().iterator();
            List<Weeklytrackchart> trackCharts = LastfmData.getInstance().getData().getWeeklytrackchart();
            while(it.hasNext()) {
                Weeklytrackchart trackChart = null;
                Weeklychartlist.Chart chart = it.next();
                for(int i = 0; i < trackCharts.size(); i++) {
                    if(((type.equals("user") && trackCharts.get(i).getUser().equals(who)) ||
                        (type.equals("group") && trackCharts.get(i).getGroup().equals(who))) &&
                            trackCharts.get(i).getFrom().equals(chart.getFrom())) {
                        trackChart = trackCharts.get(i);
                        break;
                    }
                }
                if(trackChart == null) {
                    try {
                        if(progresssCallback != null) {
                            progresssCallback.updateStatus("Reading chart " + LastfmData.dateFormat.format(LastfmData.getDateFromChart(chart.getFrom())));
                        }
                        trackChart = LastfmQuery.queryWeeklytrackchart(type, who, chart.getFrom(), chart.getTo());
                        trackCharts.add(trackChart);
                    }
                    catch(Exception e) {
                        e.printStackTrace();
                    }
                }
                if(trackChart != null) {
                    data.add(trackChart);
                }
            }
        }
        try {
            LastfmData.getInstance().store();
        }
        catch(Exception e) {
            if(progresssCallback != null) {
                progresssCallback.updateStatus("Error storing charts");
            }
            e.printStackTrace();
        }
    }

    public List<Weeklytrackchart> getCharts() {
        return data;
    }

    public void start(IProgressCallback progresssCallback) {
        new ReaderThread(progresssCallback).start();
    }

    protected class ReaderThread extends Thread {
        IProgressCallback progresssCallback;

        protected ReaderThread(IProgressCallback progresssCallback) {
            this.progresssCallback = progresssCallback;
        }

        @Override
        public void run() {
            try {
                read(progresssCallback);
                progresssCallback.finished();
            }
            catch(Exception e) {
                progresssCallback.error(e.getMessage());
            }
        }
    }
}
